#include <math.h>
//#include <malloc.h>
#include "match.h"
#include <stdlib.h>
#include "stddef.h"



Match * createMatch(short * ref, int num,int len , int Q)
{
	Match *match = malloc(sizeof(Match));
	if(!match)
		return NULL;

	match->ref = malloc(num * len * sizeof(float));
	if(!match->ref)
		return NULL;
	
	match->tmp = malloc( len * sizeof(float));
	if(!match->tmp)
		return NULL;
	
	match->num = num;
	match->len = len;
	
	float Qone = (1L<<Q);
	
	for(int n=0;n<num*len;n++)
	{
		match->ref[n] = (float)ref[n] / Qone;
	}
	
	return match;
}


float doMatchFixed(Match *match , short *vec,int ref_idx,int Q)
{
	float Qone = (1L<<Q);
	for(int n=0;n<match->len;n++)
	{
		match->tmp[n] = (float)vec[n] / Qone;
	}
	
	return doMatch(match,match->tmp,ref_idx);
}


float doMatch(Match *match , float *vec, int ref_idx)
{
	float  score = 0.0;
	float  xx = 0.0,xy =0.0,yy = 0.0;
	float * ref = &match->ref[ref_idx * match->len];

	for (int i = 0; i < match->len; ++i)
	{
		xx += vec[i] * vec[i];
		yy += ref[i] * ref[i];
		xy += vec[i] * ref[i];
	}

	if ((xx == 0) || (yy == 0))
	{
		return 0.0;
	}

#if 0
	score = xy  / sqrt(xx * yy);
#else
	score= xy * xy / (xx * yy);
#endif
	return score;
}


void releaseMatch(Match * match)
{
	if(!match)
		return;
	
	free(match->tmp);
	free(match->ref);
	free(match);
}


float MatchFloat(float *A , float *B, int len)
{
	float  score = 0.0;
	float  xx = 0.0,xy =0.0,yy = 0.0;

	for (int i = 0; i <len; ++i)
	{
		xx += A[i] * A[i];
		yy += B[i] * B[i];
		xy += A[i] * B[i];
	}

	if ((xx == 0) || (yy == 0))
	{
		return 0.0;
	}

#if 0
	score = xy  / sqrt(xx * yy);
#else
	score= xy * xy / (xx * yy);
#endif
	return score;
}

float MatchFixed(short *A , short *B, int len, int Q)
{
	float Qone = 1.0f / (float)(1L<<Q);
	float A_tmp[len];
	float B_tmp[len];
	for(int n=0;n<len;n++)
	{
		A_tmp[n] = (float)A[n] * Qone;
		B_tmp[n] = (float)B[n] * Qone;
	}
	
	return MatchFloat(A_tmp, B_tmp, len);
}


